/*
 * SDL声音控制
 * 
 * 最后修改: 2006年12月1日星期五
 * 文曦畅
 *
 * 历史:
 */

#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL_mixer.h>

#include "base.h"

#ifdef	__WIN32__
#define FREQUENCY	22050
#else
#define FREQUENCY	44100
#endif

static int channel_status[16];
static int audio_inited = 0;

static void audio_channel_done(int channel)
{
	channel_status[channel] = 0;
}

int audio_init()		//初始化,必需在video_init之后
{
	if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {	//开启音频子系统
		fprintf(stderr, "Error init audio: %s\n", SDL_GetError());
		return -1;
	}
	
	if(Mix_OpenAudio(FREQUENCY, MIX_DEFAULT_FORMAT, 2, 512) < 0) {
		//打开设备
		fprintf(stderr, "Error init audio: %s\n", SDL_GetError());
		return -1;
	}
	Mix_AllocateChannels(16);			//将通道改为16
	Mix_ChannelFinished(audio_channel_done);	//通道完成时自动释放
	audio_inited = 1;
	return 0;
}

struct Audio_sample *audio_load(char *file)
{
	char namebuf[1024];
	if (!audio_inited) return NULL;
	namebuf[0] = 0;
	strcat(namebuf, respath_get());
	strcat(namebuf, file);
	//printf("%s\n", namebuf);
	struct Audio_sample *tmp = malloc(sizeof(struct Audio_sample));
	tmp -> channel_used = -1;
	if((tmp -> sample = Mix_LoadWAV(namebuf)) == NULL) return NULL;
	return tmp;
}

int audio_play(struct Audio_sample *sample, int loop)
{
	int chan = -1, i;
	//printf("%d\n", (int)sample);
	if (!audio_inited) return -1;
	for(i = 0; i < 16; i++) {
		if(channel_status[i] == 0) {
			chan = i;
			break;
		}
	}
	if(chan == -1) return -1;
	if(Mix_PlayChannel(chan, sample -> sample, loop) == -1) {
		printf("Error playing %s\n",Mix_GetError());
		return -1;
	}
	channel_status[chan] = 1;
	sample -> channel_used = chan;
	return 0;
}

void audio_pause(struct Audio_sample *sample)
{
	if (!audio_inited) return;
	Mix_Pause(sample -> channel_used);
}

void audio_resume(struct Audio_sample *sample)
{
	if (!audio_inited) return;
	Mix_Resume(sample -> channel_used);
}

void audio_stop(struct Audio_sample *sample)
{
	if (!audio_inited) return;
	if(sample -> channel_used == -1) return;
	Mix_HaltChannel(sample -> channel_used);
	channel_status[sample -> channel_used] = 0;
	sample -> channel_used = -1;
}

void audio_free(struct Audio_sample *sample)
{
	if (!audio_inited) return;
	audio_stop(sample);
	Mix_FreeChunk(sample -> sample);
	free(sample);
}

int audio_is_playing(struct Audio_sample *sample)
{
	if (!audio_inited) return 0;
	if(sample -> channel_used == -1) return 0;
	return Mix_Playing(sample -> channel_used);
}
